/**
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if DEBUG_VERSION
if (!dafos) {
  throw new Error("Dafos namespace not found!");
}
if (!ark) {
  throw new Error("ARK namespace not found!");
}
#endif


/**
 * Constructor
 */
dafos.CodeTab = function(parent, ui) {
  LOG("[CodeTab]");
  this.appengine = new dafos.AppEngine();
  this.gadgetui = ui;
  this.codetabui = new dafos.CodeTabUI(parent);
  this.samples = {};
  
  this.gadgetui.showLoading("capabilities");
  dafos.initCallback.getCallback();
  this.appengine.canSave(
      dafos.bind(this.onCanSave, this));
    
  this.gadgetui.showLoading("samples");
  dafos.initCallback.getCallback();
  this.appengine.getOwnerSamples(
      dafos.bind(this.onSamplesLoaded, this));
      
  dafos.initCallback.addOnFinishedListener(dafos.bind(this.onLoaded, this));
};

dafos.CodeTab.prototype.onCanSave = function(data) {
  LOG("[onCanSave]", "data", data);  
  this.gadgetui.hideLoading("capabilities");
  
  dafos.cansave = (data.status == "success");
  dafos.initCallback.callback(); 
};
  
dafos.CodeTab.prototype.onSamplesLoaded = function(data) {
  LOG("[onSamplesLoaded]", "data", data);
  this.gadgetui.hideLoading("samples");
  
  this.gadgetui.setMessage(data.message);
  if (data.status == "success") {
    for (var i = 0; i < data.payload.length; i++) {
      this.samples[data.payload[i].id] = data.payload[i];
    }
  }
  dafos.initCallback.callback(); 
};

dafos.CodeTab.prototype.onLoaded = function() {
  LOG("[onLoaded]");
  var callbacks = {
	  save       : dafos.bind(this.saveCode, this),
	  saveas     : dafos.bind(this.saveCodeAs, this),
	  loadfile   : dafos.bind(this.loadCode, this),
	  deletefile : dafos.bind(this.deleteCode, this),
	  execute    : dafos.bind(this.runCode, this)
	};
	
	LOG("viewer is owner: ", dafos.opensocial.viewerIsOwner());
	dafos.cansave = dafos.cansave && dafos.opensocial.viewerIsOwner();
	this.codetabui.renderToolbar(dafos.opensocial, callbacks);  
  this.drawSamples();
};

dafos.CodeTab.prototype.drawSamples = function() {
  LOG("[drawSamples]");
  this.codetabui.clearSamplesList();
  for (var sample in this.samples) {
    if (this.samples.hasOwnProperty(sample)) {
      LOG("Sample:", sample, this.samples[sample].name, this.samples[sample].id);
      this.codetabui.addSample(this.samples[sample].name, this.samples[sample].id);
    }
  }
};

/**
 * Execute the text contained in the user's code input as javascript
 */
dafos.CodeTab.prototype.runCode = function() {
  LOG("[runCode]");
  eval(this.codetabui.getCodeText());  
  TRACK("action/execute");        
};

/**
 * 
 */
dafos.CodeTab.prototype.saveCodeAs = function() {
  LOG("[saveCodeAs]");
  var input = new ark.InputDisplay(document.body);
  var me = this;
  input.show("Save code as?", function (desired_name) { 
    if (desired_name) {
      me.current_file_name = desired_name;
      me.saveCode.apply(me); 
    }
    TRACK("action/savecodeas");
  });
};

/**
 * 
 */
dafos.CodeTab.prototype.saveCode = function () {
  LOG("[saveCode]");
  if (!this.current_file_name) {
    this.saveCodeAs.apply(this);
  } else {
    this.gadgetui.showLoading("save");
    this.appengine.saveSample(
        this.current_file_name, 
        this.codetabui.getCodeText(),
        dafos.opensocial.viewer && dafos.opensocial.viewer.getDisplayName && dafos.opensocial.viewer.getDisplayName(),
        dafos.bind(this.onCodeSaved, this));
  }
  TRACK("action/savecode");
};
  
/**
 * 
 */
dafos.CodeTab.prototype.onCodeSaved = function(data) {
  LOG("[onCodeSaved]", "data", data);
  this.gadgetui.hideLoading("save");
  
  this.gadgetui.setMessage(data.message);
  if (data.status == "success") {
    this.current_file_name = data.payload.name;
    this.current_file_key = data.payload.id;
    this.samples[data.payload.id] = data.payload;
    this.drawSamples();
    this.codetabui.renderCurrentFile(this.current_file_name,
                                     this.current_file_key);
  }
};

/**
 *
 */
dafos.CodeTab.prototype.deleteCode = function() {
  LOG("[deleteCode]");
  if (this.current_file_name) {
		this.gadgetui.showLoading("delete");
		this.appengine.deleteRecord(
		    this.current_file_key,
		    dafos.bind(this.onCodeDeleted, this));
		delete this.samples[this.current_file_name];
	}
	TRACK("action/deletecode");
};

/**
 * 
 */
dafos.CodeTab.prototype.onCodeDeleted = function(data) {
  LOG("[onCodeDeleted]", "data", data);
  this.gadgetui.hideLoading("delete");  
  
  this.gadgetui.setMessage(data.message);
  if (data.status == "success") {
		this.codetabui.clearUserOutput();
		this.codetabui.setCodeText("");
		delete this.samples[this.current_file_key];
		this.drawSamples();
    this.current_file_name = "";
    this.current_file_key = "";
		this.codetabui.renderCurrentFile("", "");
  }
};

/**
 *
 */
dafos.CodeTab.prototype.setCodeToSnippet = function(snippet) {
#ifndef MYSPACE
  if (confirm("This will clear the contents of the Code tab.  Continue?")) {
    LOG("[setCodeToSnippet]", snippet);
    this.codetabui.clearUserOutput();
    this.codetabui.setCodeText(snippet);
    this.drawSamples();
    this.current_file_name = "";
    this.current_file_key = "";
    this.codetabui.renderCurrentFile("", "");
    return true;
  } else {
    return false;
  }
#else
  LOG("[setCodeToSnippet]", snippet);
  this.codetabui.clearUserOutput();
  this.codetabui.setCodeText(snippet);
  this.drawSamples();
  this.current_file_name = "";
  this.current_file_key = "";
  this.codetabui.renderCurrentFile("", "");
  return true;
#endif
};

/**
 *
 */
dafos.CodeTab.prototype.getCode = function() {
  return this.codetabui.getCodeText();
};

/**
 *
 */
dafos.CodeTab.prototype.loadCode = function() {
  LOG("[loadCode]");
  this.current_file_name = this.codetabui.getSelectedLoadText();
  this.current_file_key = this.codetabui.getSelectedLoadValue();
  LOG("name", this.current_file_name, "key", this.current_file_key);
  this.gadgetui.showLoading("load");
  this.appengine.getSample(
      this.current_file_key,
      dafos.bind(this.onCodeLoaded, this));
  TRACK("action/loadcode");
};

/**
 * 
 */
dafos.CodeTab.prototype.onCodeLoaded = function(data) {
  LOG("[onCodeLoaded]", "data", data);
  this.gadgetui.hideLoading("load");
    
  this.gadgetui.setMessage(data.message);
  if (data.status == "success") {
    this.codetabui.clearUserOutput();
    this.codetabui.setCodeText(data.payload.text);
    this.codetabui.renderCurrentFile(
        this.current_file_name, 
        this.current_file_key);
  }
};



/**
 * Constructor
 */
dafos.CodeTabUI = function(parent) {
 this.loading_keys = {};

 this.dom_wrap = parent;
 this.dom_controls = document.getElementById("codetab_controls");
 this.dom_code_controls = document.getElementById("code_controls");
 this.dom_code = document.getElementById("code_exec");
 this.dom_filename = null;
 this.dom_handle = document.getElementById("dom_handle");
 this.dom_toolbar = document.getElementById("codetab_toolbar");
 this.dom_exec_button = null;

 this.clearUserOutput();
};


dafos.CodeTabUI.prototype.renderToolbar = function(os, callbacks) {
 var loadtext = [ "Load one of ", 
                  os.owner.getDisplayName && os.owner.getDisplayName() || "this user", 
                  "'s samples..." ].join("");

 this.dom_button_load = 
     w23.e("a", { id : "button_load", 
                  onclick : callbacks.loadfile,
                  className : "dafos-button" }, 
         w23.e("img", { src : "@server.deploy.base@/img/load.png" }), " Load");

 this.dom_button_execute = 
     w23.e("a", { id : "button_execute", 
                  onclick : callbacks.execute,
                  className : "dafos-button" }, 
         w23.e("img", { src : "@server.deploy.base@/img/execute.png" }), " Execute");

 this.dom_button_saveas =           
     w23.e("a", { id : "button_saveas", 
                  onclick : callbacks.saveas,
                  className : "dafos-button" }, 
         w23.e("img", { src : "@server.deploy.base@/img/saveas.png" }), " Save code as");

 this.dom_button_delete = 
     w23.e("a", { id : "button_delete", 
                  onclick : callbacks.deletefile,
                  className : "dafos-button" }, 
       w23.e("img", { src : "@server.deploy.base@/img/delete.png" }), " Delete");

 this.dom_button_save = 
     w23.e("a", { id : "button_save", 
                  onclick : callbacks.save,
                  className : "dafos-button" }, 
       w23.e("img", { src : "@server.deploy.base@/img/save.png" }), " Save code");

 this.dom_select = 
     w23.e("select", { id : "select_load" },
         w23.e("option", null, loadtext));

 this.dom_select.style.display = "none";
 this.dom_button_load.style.display = "none";

 if (!dafos.cansave) {
   this.dom_button_save.style.display = "none";
   this.dom_button_saveas.style.display = "none";
   this.dom_button_delete.style.display = "none";
 }

 this.dom_toolbar.appendChild(
   w23.e("table", null, 
     w23.e("tbody", null,
       w23.e("tr", null,
         w23.e("td", null, 
           this.dom_select, 
           this.dom_button_load,
           this.dom_button_saveas),
         w23.e("td", { style : { textAlign : "right", width : "auto" }},
           this.dom_button_execute
         )
       )
     )
   )
 );
 this.renderCodeControls();
 this.renderLoadedFileControls(callbacks);
 gadgets.window.adjustHeight();
};

dafos.CodeTabUI.prototype.renderLoadedFileControls = function(callbacks) {
 this.dom_filename = w23.e("div", { "id" : "filename", "className" : "subtoolbar"});
 this.dom_file_link = w23.e("a", { "target" : "_blank" });

 this.dom_filename.appendChild(
   w23.e("span", null,
     " Currently loaded ",
     w23.e("span", null, this.dom_file_link),
     " - ", 
     this.dom_button_save,
     this.dom_button_delete
   )
 );
 this.dom_filename.style.display = "none";    
 this.dom_controls.appendChild(this.dom_filename);
};

dafos.CodeTabUI.prototype.renderCodeControls = function() {
 var prop_larger = { id : "button_code_down", 
                     onclick : dafos.bind(this.codeDown, this) }; 
 var btn_larger = w23.e("a", prop_larger, "Larger");

 var prop_smaller = { id : "button_code_up", 
                      onclick : dafos.bind(this.codeUp, this) };
 var btn_smaller = w23.e("a", prop_smaller, "Smaller");

 var prop_samples = { id : "samplesbox", style : { display : "none" }};
 this.dom_samples = w23.e("div", prop_samples, "Samples");

 LOG(this.dom_samples, btn_larger, btn_smaller);
 this.dom_code_controls.appendChild(
   w23.e("table", null,
     w23.e("tbody", null,
       w23.e("tr", null,
         w23.e("td", { "className" : "samplescell" }, this.dom_samples),
         w23.e("td", { "className" : "controlcell" }, btn_larger),
         w23.e("td", { "className" : "controlcell" }, btn_smaller)
		    )
		  )
		)
	);
 gadgets.window.adjustHeight();
};


dafos.CodeTabUI.prototype.codeDown = function() {
 this.dom_code.style.height = this.dom_code.offsetHeight + 100 + "px";
 gadgets.window.adjustHeight();
};


dafos.CodeTabUI.prototype.codeUp = function() {
 this.dom_code.style.height = 
   Math.max(this.dom_code.offsetHeight - 100, 50) + "px";
 gadgets.window.adjustHeight();
};

dafos.CodeTabUI.prototype.clearSamplesList = function() {
 this.dom_select.innerHTML = "";
 this.dom_select.style.display = "none";
 this.dom_button_load.style.display = "none";
 gadgets.window.adjustHeight();
};

dafos.CodeTabUI.prototype.addSample = function(key, value) {
 this.dom_select.style.display = "inline";
 this.dom_button_load.style.display = "inline";
 params = { "value" : value };
 this.dom_select.appendChild( 
       w23.e("option", params, key));
 gadgets.window.adjustHeight();
};

dafos.CodeTabUI.prototype.getSelectedLoadValue = function() {
 return (this.dom_select && this.dom_select.value) || "";
};

dafos.CodeTabUI.prototype.getSelectedLoadText = function() {
 if (this.dom_select) {
   return this.dom_select[this.dom_select.selectedIndex].innerHTML;
 } else {
   return "";
 }
};



dafos.CodeTabUI.prototype.clearUserOutput = function() {
 this.dom_handle.innerHTML = [
   "<span class=\"dom_handle_label\">",
   '&lt;div id="dom_handle"&gt;</span>',
   "This <code>div</code> has an id of <code>dom_handle</code>",
   " that you can use to insert DOM elements into",
   "<span class=\"dom_handle_label\">&lt;/div&gt;</span>"
 ].join("");
 cls();
 gadgets.window.adjustHeight();
};

dafos.CodeTabUI.prototype.renderCurrentFile = function(name, key) {
 var select = document.getElementById("select_load"),
     node = null,
     i = 0;

 if (name && name != "") {
   this.dom_file_link.innerHTML = gadgets.util.escapeString(name);
   this.dom_file_link.href = "@server.deploy.base@/code/sample/" + key;
   this.dom_filename.style.display = "block";

   for (i = 0, node; node = select.childNodes[i]; i++) {
     if (node.value == key) {
       node.selected = "selected";
     }
   }
 } else {
   this.dom_filename.style.display = "none";
 }
 gadgets.window.adjustHeight();
};

dafos.CodeTabUI.prototype.setCodeText = function(text) {
 this.dom_code.value = text;
};

dafos.CodeTabUI.prototype.getCodeText = function() {
 return this.dom_code.value;
};




